package ca.etsmtl.log730.projet.controller.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.logging.Logger;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoService;
import org.apache.mina.core.service.IoServiceListener;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;

public class MainServer implements IoServiceListener {

	protected static final Logger logger = Logger.getLogger(MainServer.class.toString());
	
	public static Logger getLogger() {
		return logger;
	}

	private static MainServer instance = null;
	
	
	protected MainServer() {
		
	}
	
	public static MainServer getInstance() {
		if(instance == null) instance = new MainServer ();
		return instance;
	}

	public boolean isRunning() {
		return this.acceptor.isActive();
	}
	
//	public void addConnection(ServerClientChannelHandler cch) {
//		logger.info("NEW CLIENT " + cch.getSessionId().toString());
//	}
//	
//	public void removeConnection(ServerClientChannelHandler cch) {
//		logger.info("CLIENT CLOSED " + cch.getSessionId().toString());
//	}
	
    private IoAcceptor acceptor;
	public IoAcceptor getAcceptor() {
		return acceptor;
	}

	public IoSessionConfig getSessionConfig() {
		return acceptor.getSessionConfig();
	}
	private ServerSetup setup = new ServerSetup();
	private ServerClientChannelHandler handler = null;
	public void start() {
		acceptor = new NioSocketAcceptor();
		acceptor.getFilterChain().clear();
		ObjectSerializationCodecFactory oscf = new ObjectSerializationCodecFactory();
		oscf.setDecoderMaxObjectSize(1048576);
		oscf.setEncoderMaxObjectSize(1048576);
        acceptor.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(oscf));
        handler = new ServerClientChannelHandler(null,null) ;
        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        acceptor.setHandler( handler);
        acceptor.getSessionConfig().setAll(setup.getSessionConfig());
        acceptor.addListener(this);
        
        try {
			acceptor.bind( new InetSocketAddress(setup.getPort()) );
		} catch (IOException e) {
			System.err.println("CAN'T BIND TO PORT! : " + setup.getPort());
		}
	}
	

		@Override
		public void serviceActivated(IoService arg0) throws Exception {
			logger.info("SERVICE ACTIVATED");
		}

		@Override
		public void serviceDeactivated(IoService arg0) throws Exception {
			logger.info("SERVICE DEACTIVATED");
		}

		@Override
		public void serviceIdle(IoService arg0, IdleStatus arg1)
				throws Exception {
		}

		@Override
		public void sessionCreated(IoSession ios) throws Exception {
			logger.info("+++SESSION: " + ios.toString());
		}

		@Override
		public void sessionDestroyed(IoSession ios) throws Exception {
			logger.info("---SESSION: " + ios.toString());
		}

		public ServerSetup getSetup() {
			return setup;
		}

		public void setSetup(ServerSetup setup) {
			this.setup = setup;
		}

		public ServerClientChannelHandler getHandler() {
			return handler;
		}

		public void setHandler(ServerClientChannelHandler handler) {
			this.handler = handler;
		}
		
}
